﻿using HAF.Dispatcher;
using HAF.Dispatcher.Enum;
using HAF.Dispatcher.Impl;
using HAF.Dispatcher.WorkItem;
using HAF.LogUtility.Assistantor;
using HAF.LogUtility.Except;
using Iptv.ResourceGather.Model;
using Iptv.ResourceGather.SubItems;
using RDS.Core;
using RDS.Core.Utils;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;

namespace Iptv.ResourceGather
{
    /// <summary>
    /// 媒资采集任务
    /// </summary>
    public class GatherWorkItem : PluginWorkItem, IPluginRegistable
    {
        const string _defLogName = "GatherMonitor";
        /// <summary>
        /// 当前运行站点的配置
        /// </summary>
        private GatherSrvConfig _runSiteConfig;

        #region 插件接口实现
        /// <summary>
        /// 自注册函数
        /// </summary>
        /// <param name="id">工作项编号</param>
        /// <param name="objTask">工作任务对象</param>
        /// <returns></returns>
        public bool Regist(string id, object objTask)
        {
            #region 入口参数校验
            if (string.IsNullOrEmpty(id))
            {
                WriteDebugMessageExt(_defLogName, "金沙引擎：方法{0}数据解析错误：{1}", System.Reflection.MethodBase.GetCurrentMethod().Name, "参数ID为空");
                return false;
            }
            if (objTask == null)
            {
                WriteDebugMessageExt(_defLogName, "金沙引擎：方法{0}数据解析错误：{1}", System.Reflection.MethodBase.GetCurrentMethod().Name, "参数obj为空");
                return false;
            }
            #endregion 入口参数校验

            try
            {
                string taskJson = JsonAssistant.Serialize(objTask);
                WriteDebugMessage(taskJson);
                
                //创建工作项并加入执行队列
                var runJob = new GatherWorkItem()
                {
                    ID = int.Parse(TimeHelper.GetTimeStamp()),
                    TaskID = id,
                    Name = string.Concat("GatherRes", id),
                    Priority = 10,
                    Model = EnumItemModel.Multi,
                    RedoTimes = 2,
                    WorkID = _defLogName,
                    WorkJson = taskJson,
                    AllowRemoteExec = false,
                    WriteConsoleMessageEvent = RuntimeAdapter.ShowConsol,
                    WorkItems = objTask,
                    RunLogLevel = HAF.LogUtility.Enum.EnumLogLevel.All
                };
                Dispatcher.GetInstance().RegistTaskItem(runJob);

                //RuntimeControler.Tasks.Add(id, downJob);
                WriteDebugMessage(string.Format("金沙引擎：创建{0}工作项完成，下载资源请求已加入执行队列", id));
                return true;
            }
            catch (Exception ex)
            {
                WriteDebugMessage(string.Format("金沙引擎：方法{0}发生异常：{1}", System.Reflection.MethodBase.GetCurrentMethod().Name, ex.ToString()));
                return false;
            }
        }
        #endregion 插件接口实现

        /// <summary>
        /// 执行工作项
        /// </summary>
        public override void ExecItem()
        {
            base.ExecItem();
            //读取配置
            RefreshSrvConfig();
            //提取请求方输入参数
            Tack actTrace = JsonAssistant.Deserialize<Tack>(WorkJson);
            RuntimeAdapter.RunRepeat = actTrace.Action.ToLower().Equals("start");
            if (RuntimeAdapter.RunRepeat)
            {
                ShowDebugMessage("采集任务循环模式启动！");
                Thread uploadMonitor = new Thread(delegate () { CreateGatherTaskMonitor(); }) { Name = "GatherTaskMonitor", IsBackground = true, Priority = ThreadPriority.Highest };
                uploadMonitor.Start();
            }
            else
            {
                ShowWarnMessage("采集任务循环模式将被停止");
                this.Statu = EnumRunItemStatu.End;
            }
        }

        /// <summary>
        /// 获取服务侧接口配置数据
        /// </summary>
        private void RefreshSrvConfig()
        {
            _runSiteConfig = RefreshPluginConfig<GatherSrvConfig>("GatherConfig.json");
        }
        /// <summary>
        /// 获取服务侧采集规则配置数据
        /// </summary>
        private void RefreshSrvRulesCfg()
        {
            //到服务端提取采集任务
            string url = _runSiteConfig.TaskGatherHost.Replace("{srvTag}", _runSiteConfig.GatherSrvTag);
            ShowInfoMessage("到{0}获取采集任务", url);
            string rtnStr = WebHelper.GetHttpResponse(url, _runSiteConfig.TaskGatherType, "");
            if (!string.IsNullOrEmpty(rtnStr))
            {
                gatherRules.Clear();
                ShowDebugMessage(rtnStr);
                ApiResponseResult<List<GatherRuleConfig>> loadConfig = JsonAssistant.Deserialize<ApiResponseResult<List<GatherRuleConfig>>>(rtnStr);
                if (loadConfig != null && loadConfig.ReturnValue != null && loadConfig.ReturnValue.Count > 0)
                {
                    gatherRules.AddRange(loadConfig.ReturnValue);

                    string cspConfigFile = Path.Combine(RuntimeAdapter.AppDir, RuntimeAdapter.ConfigDir, _runSiteConfig.ContentProviderConfig);
                    if (File.Exists(cspConfigFile))
                    {
                        //提取进行比对
                    }
                    else
                    {
                        //输出为本地采集规则文件
                        JsonAssistant.SaveFile<List<GatherRuleConfig>>(cspConfigFile, gatherRules);
                    }
                    
                }
                else
                {
                    ShowWarnMessage("未获取到介质采集任务2");
                }
            }
            else
            {
                ShowErrMessage("未获取到介质采集任务1");
            }
        }
        /// <summary>
        /// 获取本地采集规则配置数据
        /// </summary>
        private void RefreshRulesConfig()
        {
            if (!string.IsNullOrEmpty(_runSiteConfig.ContentProviderConfig))
            {
                string cspConfigFile = Path.Combine(RuntimeAdapter.AppDir, RuntimeAdapter.ConfigDir, _runSiteConfig.ContentProviderConfig);
                if (File.Exists(cspConfigFile))
                {
                    gatherRules.Clear();
                    List<GatherRuleConfig> tmpCfg = JsonAssistant.FromFile<List<GatherRuleConfig>>(cspConfigFile);
                    if (tmpCfg!= null && tmpCfg.Count > 0)
                    {
                        gatherRules.AddRange(tmpCfg);
                    }
                    else
                    {
                        throw new RunException(RunCode.FileNotFound);
                    }
                }
                else
                {
                    ShowWarnMessage("本地采集规则配置数据不存在，启动获取服务端采集规则流程");
                    RefreshSrvRulesCfg();
                }
            }
            else
            {
                ShowErrMessage("本地采集规则配置文件配置项未赋值 ContentProviderConfig");
            }
            
        }

        List<GatherRuleConfig> gatherRules = new List<GatherRuleConfig>();

        private void CreateGatherTaskMonitor()
        {
            ShowInfoMessage("启动采集规则配置数据获取");
            //获取采集规则配置数据
            RefreshRulesConfig();

            if (gatherRules != null && gatherRules.Count > 0)
            {
                //异步执行采集任务
                while (RuntimeAdapter.RunRepeat)
                {
                    foreach (var item in gatherRules)
                    {
                        //通用配置处理
                        item.AllowExpiredTransfer = _runSiteConfig.AllowExpiredTransfer;
                        item.ExpiredTime = _runSiteConfig.ExpiredTime;
                        item.RecyclebinRoot = Path.Combine(_runSiteConfig.RecyclebinRoot, item.Code);

                        WriteInfoMessage(item.Path);
                        CreateAndExecSubItem(item);
                    }
                    //暂停六分钟
                    Thread.Sleep(6 * 60 * 1000);
                    //break;
                }

                ShowDebugMessage("循环提取任务已失效");
            }
            else
            {
                ShowErrMessage("采集规则配置数据获取失败");
            }
            
        }

        private void CreateAndExecSubItem(GatherRuleConfig gatherItem)
        {
            int runId = int.Parse(TimeHelper.GetTimeStamp());
            string runName = string.Concat("GatherRes_", gatherItem.Name, runId);
            ShowDebugMessage("创建采集任务{0}", runName);
            //创建工作项并加入执行队列
            var runItem = new GatherMediaItem()
            {
                ID = runId,
                TaskID = Guid.NewGuid().ToString("N"),
                Name = runName,
                Priority = gatherItem.Priority,
                Model = EnumItemModel.Multi,
                RedoTimes = 2,
                WorkID = string.Concat("GatherRes", gatherItem.Code),
                WorkJson = gatherItem.Path,
                AllowRemoteExec = false,
                WriteConsoleMessageEvent = RuntimeAdapter.ShowConsol,
                WorkItems = gatherItem,
                RunLogLevel = HAF.LogUtility.Enum.EnumLogLevel.All
            };

            runItem.ExecItem();
            //TimeFactoryEx runTimeFactory = new TimeFactoryEx();
            //runTimeFactory.CreateNewThreadTimer(runItem, gatherItem.Interval);
            //Dispatcher.GetInstance().RegistTaskItem(runItem);
        }
    }
}
